package nciae.db.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import nciae.db.common.CommonResult;
import nciae.db.mapper.CourseMapper;
import nciae.db.mapper.ProjectMapper;
import nciae.db.mapper.StudentMapper;
import nciae.db.pojo.dto.ApiDeleteCourseFileDTO;
import nciae.db.pojo.entity.Course;
import nciae.db.pojo.entity.Project;
import nciae.db.pojo.entity.User;
import nciae.db.pojo.vo.*;
import nciae.db.service.CourseService;
import nciae.db.utils.FileUploadUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class  CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public CommonResult search(Integer page, Integer size, Integer projectId, String lessonDate, HttpServletRequest request) {
        CommonResult<Object> result = new CommonResult<>();

        // 预加载项目名称和专家名称，避免重复查询
        Map<Integer, String> projectNameMap = projectMapper.selectList(null).stream()
                .collect(Collectors.toMap(Project::getId, Project::getProjectName, (v1, v2) -> v1));

        //查询每个项目的人数
        List<StudentCountVO> studentCountList=studentMapper.selectProjectStudentCount();
        Map<Integer, Integer> classStudentCount = studentCountList.stream()
                .collect(Collectors.toMap(StudentCountVO::getProjectId, StudentCountVO::getCount, (v1, v2) -> v1));

        DateTime start = null;

        try {
            Page<Course> pg = new Page<>(page, size);
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            User loginUser = (User)request.getSession().getAttribute("user");
            //专家登录只能看到自己要上的课表信息
            if("授课教师".equals(loginUser.getRole())){
                String realName = loginUser.getRealName();
                if(realName != null && !StringUtils.isBlank(realName)){
                    queryWrapper.eq("teacher", realName);
                }
                String department = loginUser.getDepartment();
                if(department != null && !StringUtils.isBlank(department)){
                    queryWrapper.eq("department", department);
                }
            }
            if (projectId != null) {
                queryWrapper.eq("project_id", projectId);
            }
            if (lessonDate != null && !lessonDate.isEmpty()) {
                start = DateUtil.parse(lessonDate);  // 开始时间
                queryWrapper.eq("lesson_date",start);
            }
            courseMapper.selectPage(pg, queryWrapper);
            List<Course> courses = pg.getRecords();
            long total = pg.getTotal();

            // 转换为 ExportVO
            List<CourseVO> courseVOS = courses.stream().map(course -> {
                CourseVO courseVO = new CourseVO();
                try {
                    // 复制基本属性
                    BeanUtils.copyProperties(course, courseVO);

                    courseVO.setScheduled(classStudentCount.getOrDefault(course.getProjectId(),0));

                    // 设置项目名称和专家名称（避免 NPE）
                    courseVO.setProjectName(projectNameMap.getOrDefault(course.getProjectId(), "未知项目"));
                } catch (Exception e) {
                    log.error("转换 ExportVO 失败，学员 ID: {}", course.getId(), e);
                }
                return courseVO;
            }).collect(Collectors.toList());

            result.setCode(0);
            result.setMsg("查询成功");
            result.setData(courseVOS);
            result.setCount(total);
            return result;
        } catch (Exception e) {
            result.setCode(-1);
            result.setMsg("发生错误" + e.getMessage());
            return result;
        }
    }

    @Override
    public String importExcel(MultipartFile file, Integer projectId) {
        List<Course> courseList = new ArrayList<>();
        try {
            InputStream inputStream = file.getInputStream();
            Workbook workbook = WorkbookFactory.create(inputStream);
            Sheet sheet = workbook.getSheetAt(0);

            // 获取合并单元格地址
            List<CellRangeAddress> mergeCells = getCombineCell(sheet);
            log.info("解析到的合并单元格范围：{}", mergeCells);

            for (int i = 2; i <= sheet.getLastRowNum(); i++) { // 假设数据从第3行开始
                Row row = sheet.getRow(i);
                if (row == null) {
                    log.warn("第 {} 行为空，跳过处理", i + 1);
                    continue;
                }

                // 获取日期、星期、时间段
                String dateValue = getCellValue(row.getCell(0)).trim();
                String weekValue = getCellValue(row.getCell(1)).trim();
                String timeSpanValue = getCellValue(row.getCell(2)).trim();

                // 获取日期
                if (isMergedRegion(sheet, i, 0)) {
                    dateValue = getMergedRegionValue(sheet, i, 0).trim();
                } else if (!getCellValue(row.getCell(0)).trim().isEmpty()) {
                    dateValue = getCellValue(row.getCell(0)).trim();
                }

                // 获取星期
                if (isMergedRegion(sheet, i, 1)) {
                    weekValue = getMergedRegionValue(sheet, i, 1).trim();
                } else if (!getCellValue(row.getCell(1)).trim().isEmpty()) {
                    weekValue = getCellValue(row.getCell(1)).trim();
                }

                // 获取时间段
                if (isMergedRegion(sheet, i, 2)) {
                    timeSpanValue = getMergedRegionValue(sheet, i, 2).trim();
                } else if (!getCellValue(row.getCell(2)).trim().isEmpty()) {
                    timeSpanValue = getCellValue(row.getCell(2)).trim();
                }

                // 如果这一行的关键列全部为空，则跳过
                if (dateValue.isEmpty() && weekValue.isEmpty() && timeSpanValue.isEmpty()) {
                    log.warn("第 {} 行的关键列均为空，跳过处理", i + 1);
                    continue;
                }

                // 创建 Course 实体
                Course course = new Course();
                course.setProjectId(projectId);

                try {
                    course.setLessonDate(parseStringToDate(dateValue)); // 转换为 Date 类型
                } catch (ParseException e) {
                    log.error("日期解析失败：行 {}，值：{}", i + 1, dateValue, e);
                    return "导入失败：第 " + (i + 1) + " 行，日期格式错误：" + dateValue;
                }

                course.setWeek(weekValue);
                course.setTimeSpan(timeSpanValue);

                // 设置其他字段
                course.setSubject(getCellValue(row.getCell(3)));
                course.setContent(getCellValue(row.getCell(4)));
                course.setClassHours(parseOrDefault(row.getCell(5), 0));
                course.setClassType(getOrDefault(getCellValue(row.getCell(6)), null));

                String classModeValue = getOrDefault(getCellValue(row.getCell(7)), ""); // 如果为 null，替换为空字符串
                // 替换换行符为顿号
                classModeValue = classModeValue.replace("\n", "、").replace("\r", ""); // 兼容Windows和Unix换行符
                course.setClassMode(classModeValue);

                course.setTeacher(getOrDefault(getCellValue(row.getCell(8)), null));
                course.setDepartment(getOrDefault(getCellValue(row.getCell(9)), null));
                course.setTitle(getOrDefault(getCellValue(row.getCell(10)), null));
                course.setFamous(getOrDefault(getCellValue(row.getCell(11)), null));
                course.setRegion(getOrDefault(getCellValue(row.getCell(12)), null));
                course.setAddress(getOrDefault(getCellValue(row.getCell(13)), null));

                log.info("成功解析课程数据：{}", course);
                courseList.add(course);
            }

            // 保存到数据库
            this.saveBatch(courseList);
            log.info("成功导入 {} 条数据", courseList.size());
            return "导入成功，记录条数：" + courseList.size();
        } catch (Exception e) {
            log.error("导入失败：{}", e.getMessage(), e);
            return "导入失败：" + e.getMessage();
        }
    }

//    给app端返回数据
    @Override
    public CommonResult<List<ApiTimeTableVO>> apiInfo(Integer projectId) {
        CommonResult<List<ApiTimeTableVO>> result = new CommonResult();

        try{
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("project_id", projectId);
            List<Course> courses= this.courseMapper.selectList(queryWrapper);
            List<ApiTimeTableVO> apiTimeTableVOS = new ArrayList<>();
            for (Course course : courses) {
                ApiTimeTableVO apiTimeTableVO = new ApiTimeTableVO();
                BeanUtils.copyProperties(course, apiTimeTableVO);
                apiTimeTableVOS.add(apiTimeTableVO);
            }

//            System.out.println(apiTimeTableVOS);
            if (!apiTimeTableVOS.isEmpty())
            {
                result.setData(apiTimeTableVOS);
                result.setCode(0);
                result.setMsg("发送成功");
                return result;

            }else {
                result.setCode(400);
                result.setMsg("未找到数据");
                result.setData(apiTimeTableVOS);
                return result;
            }



        }catch (Exception e){
            result.setCode(-1);
            result.setMsg(e.getMessage()+"信息有误");
            return result;

        }

    }

    @Override
    public CommonResult saveLog(Course course) {

        CommonResult result = new CommonResult();
        try {
            QueryWrapper<Course> queryWrapper = new QueryWrapper();
            queryWrapper.eq("id", course.getId());
            Course course1 = this.courseMapper.selectOne(queryWrapper);
            if (course1 != null) {
                course1.setProjectId(course.getProjectId());
                course1.setLessonDate(course.getLessonDate());
                course1.setWeek(course.getWeek());
                course1.setTimeSpan(course.getTimeSpan());
                course1.setSubject(course.getSubject());
                course1.setContent(course.getContent());
                course1.setClassHours(course.getClassHours());
                course1.setClassType(course.getClassType());
                course1.setClassMode(course.getClassMode());
                course1.setTeacher(course.getTeacher());
                course1.setDepartment(course.getDepartment());
                course1.setTitle(course.getTitle());
                course1.setAddress(course.getAddress());
                course1.setRegion(course.getRegion());
                Boolean res = updateById(course1);
                if (res) {
                    result.setCode(0);
                    result.setMsg("修改成功");
                }
                return result;
            }
            Course course2 = new Course();
            BeanUtils.copyProperties(course, course2);
            int r = courseMapper.insert(course2);
            if (r > 0) {
                result.setMsg("添加成功");
                result.setCode(0);
                return result;
            }
            result.setCode(-1);
            result.setMsg("保存信息失败");
            return result;
        } catch (Exception e) {
            result.setCode(-1);
            result.setMsg("信息有误");
            return result;
        }

    }

    @Override
    public boolean deleteById(Integer id) {
        try {
            CommonResult<String> commonResult = FileUploadUtils.deleteCourse(id);

            if (commonResult.getCode() == 0) {
                boolean isDeleted = removeById(id);
                if (isDeleted) {
                    log.info("课程删除成功{}",id);
                    return true;
                } else {
                    log.error("课程删除失败{}",id);
                    return false;
                }
            }

            return false;

        } catch (Exception e) {
            log.error("课程删除失败{}",id,e);
            return false;
        }
    }


    private Date parseStringToDate(String dateStr) throws ParseException {
        SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd"); // 用于解析完整日期
        SimpleDateFormat sdfPartial = new SimpleDateFormat("MM-dd");  // 用于解析只有月和日的日期

        // 判断日期字符串中是否包含年份
        if (!dateStr.contains("-")) {
            throw new ParseException("日期格式错误：" + dateStr, 0);
        }

        if (dateStr.matches("\\d{1,2}-\\d{1,2}")) { // 匹配只有月和日的格式，例如 3-16
            // 添加当前年份
            int currentYear = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR);
            dateStr = currentYear + "-" + dateStr; // 拼接为完整的日期格式
        }

        // 使用完整日期格式解析
        return sdfFull.parse(dateStr);
    }

    private String getCellValue(Cell cell) {
        if (cell == null) return ""; // 单元格为空
        log.info("单元格类型：{}，原始值：{}", cell.getCellType(), cell.toString());
        switch (cell.getCellType()) {
            case STRING: // 文本类型
                return cell.getStringCellValue().trim();
            case NUMERIC: // 数字或日期
                if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    return sdf.format(cell.getDateCellValue());
                }
                return String.valueOf((int) cell.getNumericCellValue());
            case BOOLEAN: // 布尔类型
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA: // 公式类型
                try {
                    return cell.getStringCellValue().trim();
                } catch (IllegalStateException e) {
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BLANK: // 空白单元格
                return ""; // 返回空字符串
            default: // 其他类型
                return cell.toString().trim();
        }
    }

    private Integer parseOrDefault(Cell cell, Integer defaultValue) {
        String value = getCellValue(cell);
        try {
            return value.isEmpty() ? defaultValue : Integer.parseInt(value);
        } catch (NumberFormatException e) {
            log.warn("学时解析失败，默认值使用：{}", defaultValue, e);
            return defaultValue;
        }
    }

    private String getOrDefault(String value, String defaultValue) {
        return (value == null || value.trim().isEmpty()) ? defaultValue : value.trim();
    }

    private boolean isMergedRegion(Sheet sheet, int row, int column) {
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            if (row >= range.getFirstRow() && row <= range.getLastRow() &&
                    column >= range.getFirstColumn() && column <= range.getLastColumn()) {
                log.debug("第 {} 行第 {} 列是合并单元格，范围：{}", row + 1, column, range);
                return true;
            }
        }
        return false;
    }

    private String getMergedRegionValue(Sheet sheet, int row, int column) {
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            if (row >= range.getFirstRow() && row <= range.getLastRow() &&
                    column >= range.getFirstColumn() && column <= range.getLastColumn()) {
                Row firstRow = sheet.getRow(range.getFirstRow());
                Cell firstCell = firstRow.getCell(range.getFirstColumn());
                String value = getCellValue(firstCell);
                log.debug("合并单元格范围：{}，值：{}", range, value);
                return value;
            }
        }
        log.warn("第 {} 行第 {} 列未找到合并单元格", row + 1, column);
        return "";
    }

    private List<CellRangeAddress> getCombineCell(Sheet sheet) {
        List<CellRangeAddress> mergeCells = new ArrayList<>();
        int mergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < mergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            log.info("合并单元格范围：{}", range);
            mergeCells.add(range);
        }
        return mergeCells;
    }



   //    后台获取所有课件信息
    @Override
    public CommonResult<CourseFilesVo> getCourseFiles(Integer courseId) {
        CommonResult<CourseFilesVo> result = new CommonResult<>();
        Course course= this.getById(courseId);
        CourseFilesVo courseFilesVo = new CourseFilesVo();
       try {
           courseFilesVo.setId(course.getId());
           courseFilesVo.setProjectId(course.getProjectId());
           courseFilesVo.setTeacher(course.getTeacher());
           courseFilesVo.setSubject(course.getSubject());
           courseFilesVo.setContent(course.getContent());
           courseFilesVo.setClassType(course.getClassType());
           if (course.getUrlFile()!=null) {
               System.out.println(course.getUrlFile());
               courseFilesVo.setUrl_file(getCourseFilesUrl(course.getUrlFile()));
           }
       result.setCode(0);
       result.setMsg("获取课件信息成功");
       result.setData(courseFilesVo);
       return  result;
      } catch (Exception e) {
           result.setCode(-1);
           result.setMsg("获取课件信息失败");
       }
        return result;
    }

    @Override
    public CommonResult<ApiCourseFilesVo> getUrlFiles(Integer courseId, String fileName) {
        CommonResult<ApiCourseFilesVo> result = new CommonResult<>();
        try {
            //1 拿到文件的url
            String file_url=FileUploadUtils.FILE_URL+"CourseFiles"+"/"+courseId+"/"+"file"+"/"+fileName;
            ApiCourseFilesVo apiCourseFilesVo =new ApiCourseFilesVo();
            //拿到filename的uuid
            String uuid =fileName.split("_", 2)[0];

            //图片的真实路径
            String path=FileUploadUtils.FILE_PATH+"CourseFiles"+File.separator+courseId+File.separator+"img"+File.separator+uuid;
            List<String> filenames=  getCourseFilesUrl(path);
            //图片的url
            String image_url=FileUploadUtils.FILE_URL+"CourseFiles"+"/"+courseId+"/"+"img"+"/"+uuid;
            List<String> fullImageUrls = new ArrayList<>();
            for (String filename : filenames) {
                fullImageUrls.add(image_url+"/"+filename);
            }
            apiCourseFilesVo.setId(courseId);
            apiCourseFilesVo.setUrl_file(file_url);
            apiCourseFilesVo.setUrl_img(fullImageUrls);
            result.setCode(0);
            result.setMsg("获取url信息成功");
            result.setData(apiCourseFilesVo);
        }catch (Exception e)
            {
                result.setCode(-1);
                result.setMsg("获取url信息失败");
            }

        return result;
    }

    @Override
    public boolean updateCourseFile(MultipartFile file, Integer courseId) {

        CommonResult<String> commonResult = FileUploadUtils.uploadCourseFiles(file, courseId);
        if(commonResult.getCode() != 0){
            return false;
        }
        String path = commonResult.getData();
        File file1 = new File(path);
        Course course = courseMapper.selectById(courseId);
        //文件名
        String fileName = file1.getName();
        //获取后缀
        String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();

        if (fileExtension.equals("pdf")||fileExtension.equals("ppt")||fileExtension.equals("pptx")||fileExtension.equals("docx")||fileExtension.equals("doc")||fileExtension.equals("xls")||fileExtension.equals("xlsx"))
        {
            String uuid =fileName.split("_", 2)[0];
            CommonResult<String> commonResult1 = FileUploadUtils.convertToImages(path,courseId,uuid);
            if (commonResult1.getCode()==0){
                System.out.println("转化成图片成功");
                //如果转化成图片成功时
                if (course.getUrlImg()==null||course.getUrlImg().isEmpty()) {
                    String urlImg = FileUploadUtils.FILE_PATH + "CourseFiles" + File.separator + courseId + File.separator + "img";
                    course.setUrlImg(urlImg);
                }
            }
        }
        //文件的相对路径
        if (course.getUrlFile()==null||course.getUrlFile().isEmpty()) {
            String urlFile = FileUploadUtils.FILE_PATH + "CourseFiles" + File.separator + courseId + File.separator + "file";
            course.setUrlFile(urlFile);
            courseMapper.updateById(course);
        }

        return true;
    }

    // 拿到所有的名字返回
    private List<String> getCourseFilesUrl(String path) {
        List<String> fileNames = new ArrayList<>();
        File dir =new File(path);
        if (dir.exists() && dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    System.out.println(file.getName());
                    fileNames.add(file.getName());
                }
            }
        }
        return fileNames;
    }

}


